#pragma once
#include "fields.hpp"
#include <functional>
#include <memory>
namespace myrpc{
    class BaseMessage{
        public:
            using ptr=std::shared_ptr<BaseMessage>;
            // virtual ~BaseMessage();
            virtual void setId(std::string id)
            {
                _rid=id;
            }
            virtual std::string rid()
            {
                return _rid;
            }
            virtual void setMType(MType mtype)
            {
                _mtype=mtype;
            }
            virtual MType mtype()
            {
                return _mtype;
            }

            virtual std::string serialize()=0;
            virtual bool unserialize(const std::string& msg)=0;
            virtual bool check()=0;
        private:
            MType _mtype;
            std::string _rid;
    };
    class BaseBuffer{
        public:
            using ptr=std::shared_ptr<BaseBuffer>;
            //1、用来缓冲区当前有多少数据
            virtual size_t readAbleSize()=0;

            //尝试从缓冲区取出4字节的数据（不删除）
            virtual int32_t peekInt32()=0;
            //删除缓冲区4字节的数据
            virtual void retrieveInt32()=0;
            //从缓冲区取出4字节的数据并删除
            virtual int32_t readInt32()=0;
            //根据长度从缓冲区种取出相应的数据
            virtual std::string retrieveAsString(size_t len)=0;
    };
    class BaseProtocol{
        public:
            using ptr=std::shared_ptr<BaseProtocol>;
            //判断是否可以处理
            virtual bool canProcessed(const BaseBuffer::ptr &buf)=0;
            //设置接收到的数据对应的回调函数
            virtual bool onMessage(const BaseBuffer::ptr &buf,BaseMessage::ptr &msg)=0;
            //发送数据前进行序列化
            virtual std::string serialize(const BaseMessage::ptr &msg)=0;
    };
    class BaseConnection{
        public:
            using ptr=std::shared_ptr<BaseConnection>;
            virtual void send(const BaseMessage::ptr &msg)=0;
            virtual void shutdown()=0;
            //判断是否连接
            virtual bool connected()=0;
    };
    using ConnectionCallback=std::function<void(const BaseConnection::ptr&)>;
    using CloseCallback=std::function<void(const BaseConnection::ptr&)>;
    using MessageCallback=std::function<void(const BaseConnection::ptr&,BaseMessage::ptr&)>;
    class BaseServer{
        public:
            using ptr=std::shared_ptr<BaseServer>;
            virtual void setConnectionCallback(const ConnectionCallback& cb)
            {
                _cb_connection=cb;
            }
            virtual void setCloseCallback(const CloseCallback& cb)
            {
                _cb_close=cb;
            }
            virtual void setMessageCallback(const MessageCallback& cb)
            {
                _cb_message=cb;
            }
            virtual void start()=0;
        protected:
            ConnectionCallback _cb_connection;
            CloseCallback _cb_close;
            MessageCallback _cb_message;
    };
    class BaseClient{
        public:
            using ptr=std::shared_ptr<BaseClient>;
            virtual void setConnectionCallback(const ConnectionCallback& cb)
            {
                _cb_connection=cb;
            }
            virtual void setCloseCallback(const CloseCallback& cb)
            {
                _cb_close=cb;
            }
            virtual void setMessageCallback(const MessageCallback& cb)
            {
                _cb_message=cb;
            }
            virtual void connect()=0;
            virtual void shutdown()=0;
            virtual bool send(const BaseMessage::ptr&)=0;
            //获取一个连接
            virtual BaseConnection::ptr connection()=0;
            virtual bool connected()=0;
        protected:
            ConnectionCallback _cb_connection;
            CloseCallback _cb_close;
            MessageCallback _cb_message;
    };    
}